package com.deeper.customview.ui.c4.exercise.c04e01;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

import java.util.ArrayList;
import java.util.List;

/**
 * 编写一个双人对战的五子棋游戏，要求：
 * A 黑白双方对战
 * B 可以选择哪一方先下
 * C 用户可以定制棋子大小和棋盘大小
 * D 用虚线框标明最后下的棋子
 * E 判断胜负
 * <p>
 * //TODO 仅完成了绘制，其余功能没实现
 */
public class FiveChessView extends View {
    private Paint paint;

    private ArrayList<Chess> chessList;
    private final int chessRadius = 60;
    private static final int OFFSET = 10;//发光点的偏移大小
    private int chessBoardRows;
    private int chessBoardColumns;
    private int width;
    private int height;

    private final ChessType firstChessType = ChessType.WHITE;


    public FiveChessView(Context context) {
        super(context);
    }


    public FiveChessView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);

        chessList = new ArrayList<>();
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    }


    public FiveChessView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        width = getMeasuredWidth();
        height = getMeasuredHeight();
        chessBoardRows = height / (chessRadius * 2);
        chessBoardColumns = width / (chessRadius * 2) - 1;
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        //画棋盘
        drawChessBoard(canvas, chessBoardRows, chessBoardColumns);
        //画棋子
        drawChessList(canvas, chessList);
    }


    private void drawChessBoard(Canvas canvas, int rows, int cols) {
        //画竖线
        canvas.save();
        canvas.translate(20, 20);
        paint.reset();
        for (int i = 0; i < cols + 1; i++) {
            canvas.drawLine(0, 0, 0, rows * chessRadius * 2, paint);
            canvas.translate(chessRadius * 2, 0);
        }
        canvas.restore();

        //画横线
        canvas.save();
        canvas.translate(20, 20);

        for (int i = 0; i < rows + 1; i++) {
            canvas.drawLine(0, 0, cols * chessRadius * 2, 0, paint);
            canvas.translate(0, chessRadius * 2);
        }
        canvas.restore();
    }


    private void drawChessList(Canvas canvas, List<Chess> chessList) {
        for (Chess chess : chessList) {
            canvas.save();
            canvas.translate(20, 20);

            canvas.translate(chess.column * chessRadius * 2, chess.row * chessRadius * 2);
            int color = chess.color == ChessType.BLACK ? Color.BLACK : Color.GRAY;
            RadialGradient rg = new RadialGradient(0 + OFFSET, 0 + OFFSET, chess.radius, Color.WHITE, color, Shader.TileMode.MIRROR);
            paint.reset();
            paint.setStyle(Paint.Style.FILL);
            paint.setShader(rg);
            canvas.drawCircle(0, 0, chess.radius, paint);
            paint.setShader(null);

            paint.reset();
            if (chess.lastChess) {
                paint.setStyle(Paint.Style.STROKE);
                paint.setColor(Color.RED);
                paint.setStrokeWidth(5);
                for (int i = 0; i < 18; i++) {
                    canvas.drawArc(new RectF(-chessRadius, -chessRadius, chessRadius, chessRadius), 0, 7, false, paint);
                    canvas.rotate(20, 0, 0);
                }
            }
            canvas.restore();
        }
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_UP:
                //这里产生新的棋子
                //判断当前坐标对应的最近的棋位
                int currentRow = Math.round(y / (chessRadius * 2f));
                int currentColumn = Math.round(x / (chessRadius * 2f));
                if (!exist(currentRow, currentColumn) && inBoard(currentRow, currentColumn)) {
                    Chess newChess = new Chess();
                    newChess.radius = chessRadius;
                    newChess.column = currentColumn;
                    newChess.row = currentRow;
                    if (chessList.isEmpty()) {
                        newChess.color = firstChessType;
                        newChess.lastChess = true;
                    } else {
                        Chess previousChess = chessList.get(chessList.size() - 1);
                        previousChess.lastChess = false;
                        newChess.color = previousChess.color == ChessType.WHITE ? ChessType.BLACK : ChessType.WHITE;
                        newChess.lastChess = true;
                    }
                    chessList.add(newChess);

                    invalidate();
                }
                break;
        }
        return true;
    }


    private boolean exist(int row, int column) {
        for (Chess chess : chessList) {
            if (chess.column == column && chess.row == row) {
                return true;
            }
        }
        return false;
    }


    private boolean inBoard(int row, int column) {
        return row <= chessBoardRows && column <= chessBoardColumns;
    }
}
